﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Light.Framework.Contract;
using DbLinq.Data.Linq;
using System.Reflection;
using System.Data;
using System.Data.Common;
using System.IO;
using Light.Framework.Castle;

namespace Light.Framework
{

    /// <summary>
    /// SQL语句执行类
    /// </summary>
    public abstract class SQLExecuter
    {

        private static IDbHelper _SQLHelper = null;
        private static DbProviderFactory _Factory = null;
        private static IDbConnection _DbConnection = null;

        /// <summary>
        /// 自定义数据库访问对象
        /// </summary>
        public static IDbHelper SQLHelper
        {
            get
            {

                if (_SQLHelper == null)
                {
                    string assemblyPath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Light.Framework.dll");
                    string typeName = "Light.Framework.DbHelper." + Database.ToString() + "SqlHelper";

                    _SQLHelper = Assembly.LoadFrom(assemblyPath).CreateInstance(typeName) as IDbHelper;
                }

                return _SQLHelper;
            }
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        public SQLExecuter()
        {
            if (_DbConnection == null)
            {
                _DbConnection = SQLHelper.CreateDbConnection();
            }
            _Factory = DbProviderFactories.GetFactory(ProviderInvariantName);
        }

        /// <summary>
        ///
        /// </summary>
        public static DataContext DataContext
        {
            get;
            set;
        }


        /// <summary>
        ///  数据库提供器常量名
        /// </summary>
        public static string ProviderInvariantName
        {
            get
            {
                if (_DbConnection == null)
                    _DbConnection = SQLHelper.Connection;

                return _DbConnection.GetType().Namespace;
            }
        }


        /// <summary>
        /// 当前数据库类型
        /// </summary>
        public static Database Database
        {
            get
            {
                Database dbType = Database.Firebird;

                string dbTypeString = System.Configuration.ConfigurationManager.AppSettings["DbType"];

                if (String.IsNullOrEmpty(dbTypeString))
                {
                    return Database;
                }

                dbTypeString = dbTypeString.ToUpper().Trim();

                if (Database.Firebird.ToString().ToUpper() == dbTypeString)
                {
                    dbType = Database.Firebird;
                }
                else if (Database.MySQL.ToString().ToUpper() == dbTypeString)
                {
                    dbType = Database.MySQL;
                }
                else if (Database.SqlServer.ToString().ToUpper() == dbTypeString)
                {
                    dbType = Database.SqlServer;
                }
                else if (Database.Oracle.ToString().ToUpper() == dbTypeString)
                {
                    dbType = Database.Oracle;
                }

                return dbType;
            }
        }

        #region CreateParameter

        public static IDbDataParameter CreateParameter()
        {
            IDbDataParameter[] parames = CreateParameter(1);
            return parames[0];
        }

        public static IDbDataParameter CreateParameter(string name, object value)
        {
            IDbDataParameter parame = CreateParameter();
            SetParameter(parame, name, value);

            return parame;
        }

        public static void SetParameter(IDataParameter parame, string name, object value)
        {
            parame.ParameterName = name;

            if ((parame.GetType().Name == "OracleParameter"))
            {
                if (value is Guid)
                {
                    parame.DbType = DbType.AnsiStringFixedLength;
                    parame.Value = value.ToString();
                }
                else if (value is String && ((string)value).Length == 0)
                {
                    parame.Value = new string(' ', 1);
                }
                else
                {
                    parame.Value = value;
                }
            }
            else
            {
                parame.Value = value;
            }
        }

        public static IDbDataParameter[] CreateParameter(int size)
        {
            if (size <= 0)
                throw new ArgumentException("size:" + size);
            if (_Factory == null)
                _Factory = DbProviderFactories.GetFactory(ProviderInvariantName);

            IDbDataParameter[] parameters = new IDbDataParameter[size];
            for (int i = 0; i < size; i++)
            {
                parameters[i] = _Factory.CreateParameter();
            }
            return parameters;
        }

        #endregion
    }
}
